<template>
  <div class="goods-spec">
    <div class="goods-sku" v-for="(spec, i) in props.goodsDetails.specs" :key="i">
      <div class="spec-name">{{ spec.name }}</div>
      <div class="box">
        <div
          v-for="(d, j) in spec.values"
          :key="j" :class="spec.disabled[j] ? 'click-pass' : 'click-ban'"
          @click="spec.disabled[j] ? onChangePrice(spec, d, i) : ''"
        >
          <div
            :class="specChecked[i]?.valueName !== d.name ? 'goods-sku-num' : 'goods-sku-num border'"
            v-if="d.picture === null" :title="d.name"
          >
            {{ d.name }}
          </div>
          <div v-else :class="specChecked[i]?.valueName !== d.name ? 'goods-sku-img' : 'goods-sku-img color'">
            <img :src="d.picture" alt="" :title="d.name">
          </div>
        </div>
      </div>
    </div>
    <el-button type="success" class="layer-btn" @click="onChangeSkus">确认</el-button>
  </div>
</template>

<script setup>
import { useStore } from 'vuex';
import { ref, watch } from 'vue';

const store = useStore();

// 初始默认价格
const defaultOldPrice = ref();
const defaultPrice = ref();
// 选中分组和属性列表
const specChecked = ref([]);
// 选中组合的ID
const skusId = ref('');

const props = defineProps({
  goodsDetails: {
    type: Object,
  },
  rowData: {
    type: Object,
  },
});

const emit = defineEmits([
  'layerUpdate',
  'onDeleteShopping',
]);

// 监听对象
const updateOne = watch(
  // 这种写法会侦听到 props 中 test 的变化
  () => props.goodsDetails,
  () => {
    if (props.goodsDetails.skus) {
      const attrsText = props.rowData.attrsText.split(' ').filter((item) => item);
      specChecked.value = attrsText.map((item) => {
        const temp = item.split(':');
        return {
          name: temp[0],
          valueName: temp[1],
        };
      });
      updateOne();
    }
  },
);

// 判断数组是否包含对象   // 1次修改
function hasObjInArr(obj, arr) {
  return arr.some((item) => {
    if (Object.prototype.toString.call(obj) !== '[object Object]') {
      return item === obj;
    }
    const exists = item.filter((temp) => JSON.stringify(obj) === JSON.stringify(temp));
    return exists.length > 0;
  });
}

// 商品参数选择后设置新的价格和id
function setSkusPrice() {
  for (let i = 0; i < props.goodsDetails.skus.length; i++) {
    let isValue = true;
    const item = props.goodsDetails.skus[i];
    for (let j = 0; j < item.specs.length; j++) {
      if (item.specs[j].name !== specChecked.value[j]?.name || item.specs[j].valueName !== specChecked.value[j]?.valueName) {
        isValue = false;
        break;
      }
    }
    if (isValue) {
      skusId.value = item.id;
      return item;
    }
  }
  // 2次修改
  defaultOldPrice.value = props.goodsDetails.value.oldPrice;
  defaultPrice.value = props.goodsDetails.value.price;
}

// 设置商品是否可用   // 1次修改
function setSpecsDisabledV2(data) {
  /**
   实现原理：
   下文中关键词说明实例：
   颜色： 黑色，白色
   其中[颜色]为【分组】，[黑色/白色]为【属性】
   1 判断属性是否有效
   2 遍历specs，依次判断每个分组
   3 获取有效组合
   3.1 遍历skus，依次判断value
   3.2 库存（inventory）为0的不要
   3.3 如果选中的记录为0，则保留
   3.4 判断skus中value，必须包含所有被选中的分组和属性
   4 遍历属性，判断是否在有效组合中
   */
  const { skus } = data;
  // 获取选中的分组数量
  // const specCheckTotal = specChecked.value.filter((item) => item.name).length;

  for (let i = 0; i < data.specs.length; i++) {
    const spec = data.specs[i];
    // 判断当前分组是否已经被选中
    // const exists = specChecked.value.some((item) => item.name === spec.name);
    // if (exists) { // 已经被选中的不做判断
    //   continue;
    // }
    // 获取被选中的分组，且有库存
    const checkSkus = skus.filter((sku) => {
      if (sku.inventory === 0) { // 没有库存的不要，要先判断库存
        return false;
      }
      if (specChecked.value.length === 0) { // 如果一个没选，则返回全部
        return true;
      }
      const specCheckList = specChecked.value.filter((item) => item.name && item.name !== spec.name);
      const specCheckTotal = specCheckList.length;
      // skus的specs中必须包含已经选中的
      let skuSpecExists = 0;
      for (let j = 0; j < sku.specs.length; j++) {
        const skuSpec = sku.specs[j];
        const skuSpecExist = specCheckList.some((item) => item.name === skuSpec.name && item.valueName === skuSpec.valueName);
        skuSpecExists += skuSpecExist ? 1 : 0;
      }
      return skuSpecExists === specCheckTotal;
    });
    // 只要skus中的specs
    const checkSkusSpecs = checkSkus.map((item) => item.specs);
    data.specs[i] = {
      ...data.specs[i],
      disabled: data.specs[i].values.map(({ name }) => hasObjInArr({ name: spec.name, valueName: name }, checkSkusSpecs)),
    };
  }
  return data;
}

// 点击事件
function onChangePrice(spec, value, i) {
  // 2次修改
  if (specChecked.value[i]?.name === spec.name && specChecked.value[i]?.valueName === value.name) {
    specChecked.value[i] = {};
  } else {
    specChecked.value[i] = {
      name: spec.name,
      valueName: value.name,
    };
  }
  setSkusPrice();
  // 1次修改
  setSpecsDisabledV2(props.goodsDetails);
}
// 确认修改组合
async function onChangeSkus() {
  // 删除旧商品
  await store.dispatch('home/delShoppingCartList', { ids: [props.rowData.skuId] });
  await store.dispatch('home/addShoppingCartList', { count: 1, skuId: skusId.value });
  await emit('layerUpdate'); // 第一个是事件，data为传递的参数
}

</script>

<style lang="scss" scoped>

.goods-spec{
  flex: 1;
  box-sizing: border-box;
  .goods-sku-img{
    height: 50px;
    width: 50px;
    border: 1px solid #e4e4e4;
    margin: 0  6px 6px 0;  // todo 3  // 1次修改
    img{
      height: 50px;
      width: 50px;
      margin: 0 10px 5px 0;
    }
  }
  :deep(.el-form-item){
    margin-top: 16px;
    margin-left: 10px;
  }
  :deep(.el-form-item__label){
    padding: 0 16px 0 0 ;
  }
  :deep(.el-radio__input){
    display: none;
  }

  .goods-sku-img, goods-sku-num {
    cursor: pointer;
  }

  .goods-spec-name{
    font-size: 22px;
    margin: 0;
    padding-bottom: 10px;
  }
  .goods-spec-desc{
    font-size: 14px;
    color: #999;
    margin: 0;
    padding-bottom: 10px;
  }
  .goods-spec-price{
    margin: 0;
    padding-bottom: 10px;
    & span:nth-child(1){
      font-size: 22px;
      color: #cf4444;
      margin-right: 10px;
    }
    & span:nth-child(2){
      color: #999;
      text-decoration: line-through;
    }
  }
  .goods-serve{
    width: 500px;
    padding: 20px 10px 0;
    background: #f5f5f5;
    div{
      padding-bottom: 10px;
      :deep(.el-select){
        padding: 0;
        line-height: 0;
      }
      & span:nth-child(1){
        color: #999;
        font-size: 14px;
        margin-right: 16px;
      }
      & span:nth-child(2){
        color: #666;
        font-size: 14px;
      }
      span .point{
        color: #27ba9b;
        margin: 0;
      }
      .serve-color{
        color: #666;
        font-size: 14px;
        padding-left: 8px;
      }
      .serve-color-more{
        color: #27ba9b;
        font-size: 14px;
        padding-left: 8px;
      }
    }
  }
  .goods-sku{
    display: flex;
    padding: 10px 0 0 10px;
    align-items: center;
    .spec-name{
      width: 50px;
      font-size: 14px;
      color: #999;
    }
    .box{
      display: flex;
      flex: 1;
      flex-wrap: wrap;
      .goods-sku-num{
        border: 1px solid #e4e4e4;
        color: #666;
        height: 30px;
        line-height: 30px;
        text-align: center;
        padding: 0 20px;
        font-size: 14px;
        margin: 0  6px 6px 0;
      }
      .border{
        border: 1px solid #27ba9b;
      }
      .color{
        border: 1px solid #27ba9b;
      }
    }
  }
  .goods-num{
    display: flex;
    padding: 20px 0 0 10px;
    & div:nth-child(1){
      width: 50px;
      line-height: 30px;
      color: #999;
      font-size: 14px;
    }
  }
  .goods-btn{
    margin-top: 20px;
    button{
      width: 180px;
      height: 50px;
      padding: 1px 6px;
      background: #27ba9b;
      border: none;
      color: #fff;
      border-radius: 4px;
      font-size: 18px;
    }
  }
}


.click-pass {
  cursor: pointer;
}
.click-ban {
  cursor: not-allowed;
  .goods-sku-num, .goods-sku-img {
    border: 1px dashed #eee !important;
    opacity: .6;
  }
}

.layer-btn {
  margin-left: 60px;
  margin-top: 10px;
}
</style>
